#include <REGX52.H>
#include "DS18B20.h"
#include "LCD1602.h"
#include "Delay.h"
#include "AT24C02.h"
#include "Timer0.h"
#include "KeyTimer0.h"

/*用定时器扫描按键的话，函数需要经常进入中断，
单总线的延时（**us）非常严格，进入中断会打乱原来的时序
解决方法：在当前写的单总线库里把所有函数 中断关掉(EA=0)，结束再打开(EA=1)
按键可以正常扫描
这种关掉总中断的方法，单总线通信延时问题解决了，但是定时器计时功能受很大影响
本程序没有严格的计时（类似 秒表时钟），本程序只用了定时器扫描独立按键优先级低于单总线
注意综合其他模块时，会干扰其他模块
如果想要（定时器扫描数码管或按键）与（DS18B20温度读取）都是最高优先级，
可以考虑独立扫描数码管的芯片，
*/





float T,TShow;/*多定义了个TShow，让TShow改变而原本的T(有正负)不改变，便于后边报警判断*/
char TLow,THigh;//温度下限，上限
unsigned char K_KeyNum;


void main()
{
	DS18B20_ConvertT();	//最开始转换一次温度
	Delay(1000);//第一次读取，就不会有默认温度数值了
	
	THigh = AT24C02_ReadByte(0);//上电 把之前存入的上限 读取回来
	TLow  = AT24C02_ReadByte(1);//上电 把之前存入的下限 读取回来
	if(THigh>125 || TLow<-55 || THigh<=TLow)
		{THigh=35;TLow=15;}//如果数据不对，给两个默认值
	
	LCD_Init();//初始化
	LCD_ShowString(1,1,"T:");	//实际温度提示
		LCD_ShowChar(1,10,0xDF);//这两行显示摄氏度符号
	LCD_ShowChar(1,11,'C');
	LCD_ShowString(2,1,"TH:");	//温度上限提示
	LCD_ShowString(2,9,"TL:");	//温度下限提示
	LCD_ShowSignedNum(2,4,THigh,3);	//这两行是提前显示一下，因为后边写的是 按键按下才会刷新显示
	LCD_ShowSignedNum(2,12,TLow,3);
	Timer0_Init();
		
		
	while(1)
	{
		K_KeyNum = GetKey_Num();//获取键码数值
		
		/*温度读取及显示*/
		DS18B20_ConvertT();	//转换温度
		T = DS18B20_ReadT();//
		if(T<0)
		{
			LCD_ShowChar(1,3,'-');//显示负号
			TShow = -T;//TShow 改变了，T 并没有改变
		}
		else
		{
			LCD_ShowChar(1,3,'+');
			TShow = T;//正数T直接赋值给TShow
		}
		LCD_ShowNum(1,4,TShow,3);//(整数部分)第一行第四列显示 T 占3位
		LCD_ShowChar(1,7,'.');
		LCD_ShowNum(1,8,(unsigned long)(TShow*100)%100,2);
		
		/*阈值判断及显示*/
		
		if(K_KeyNum)//如果按键按下才会刷新显示，这样不用一直扫描了，节省时间，以后也可以这样写
		{
			if(K_KeyNum == 1)
			{
				THigh++;
				if(THigh>125) THigh=125;//越界判断
			}
			if(K_KeyNum == 2)
			{
				THigh--;
				if(THigh<=TLow) THigh++;//越界，THigh自加
			}
			if(K_KeyNum == 3)
			{
				TLow++;
				if(TLow>=THigh) TLow--;//越界，TLow自减，两者不会相等
			}
			if(K_KeyNum == 4)
			{
				TLow--;
				if(TLow<-55) TLow=-55;//越界判断
			}
			
			LCD_ShowSignedNum(2,4,THigh,3);	//显示有符号的数字
			LCD_ShowSignedNum(2,12,TLow,3);
			
			AT24C02_WriteByte(0,THigh);
			Delay(5);//把THigh存入第0位地址，并且延时5ms
			AT24C02_WriteByte(1,TLow);
			Delay(5);	//把 TLow存入第1位地址，并且延时5ms
			
		}
		
		if(T > THigh) {LCD_ShowString(1,13,"OV:H");}
		else if(T < TLow ) {LCD_ShowString(1,13,"OV:L");}
		else {LCD_ShowString(1,13,"    ");}
		
	}
	
}



void Timer0_Routine() interrupt 1  //定时器0的中断函数
{
	static unsigned int T0Count;//static静态局部变量，只有本函数能引用
	//退出函数不丢失T0Count变量
	
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	T0Count++;
	if(T0Count>=10)
	{
		KeyScan();
		T0Count=0;
	}
	
}